<template>
    <el-dialog
        v-model="dialogVisible"
        @close="closeDialog"
        :title="`${title}${maxTitle}`"
        :close-on-click-modal="false"
        width="300px"
    >
        <div class="pb10">
            <el-input
                v-model="params.keyword"
                @keyup.enter="mdSearch"
                @clear="mdSearch"
                :placeholder="placeholder"
                clearable
            >
                <template #suffix>
                    <el-icon @click="mdSearch" pointer>
                        <Search/>
                    </el-icon>
                </template>
            </el-input>
        </div>
        <div class="flex pb10">
            <el-select v-model="params.first_industry" @change="changeFirstIndustry" :clearable="!!params.first_industry">
                <el-option v-for="row in firstIndustry" :key="row.id" :value="row.id" :label="row.name"/>
            </el-select>
            <el-select v-model="params.second_industry" ml6 @change="changeSecondIndustry" :clearable="!!params.second_industry">
                <el-option v-for="row in secondIndustry" :key="row.id" :value="row.id" :label="row.name"/>
            </el-select>
        </div>
        <el-table
            ref="multipleTableRef"
            :empty-text="emptyText"
            :data="searchListData"
            :row-key="getRowKeys"
            style="width: 100%;"
            height="300"
            :show-header="false"
            @selection-change="handleSelectionChange"
            v-loading="tableLoading"
            element-loading-background="rgba(0,0,0,0)"
            class="model-table-border-none"
        >
            <el-table-column :reserve-selection="true" type="selection" width="30"/>
            <el-table-column property="name" min-width="230" show-overflow-tooltip/>
        </el-table>

        <template #footer>
            <ul class="f-c-b pl5">
                <li>
                    <el-checkbox
                        v-if="!isMax"
                        :disabled="disLoading"
                        v-model="checkAll"
                        :indeterminate="indeterminate"
                        @change="handleCheckAll"
                    >
                        全选
                    </el-checkbox>
                </li>
                <li>
                    <el-button @click="cancelDialog">取消</el-button>
                    <el-button type="primary" :loading="disLoading" :disabled="disLoading" @click="onDialog">确认</el-button>
                </li>
            </ul>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
    import { computed, nextTick, ref, watch } from 'vue';
    import { ElMessage, ElTable } from "element-plus";
    import { Search } from '@element-plus/icons-vue'
    import { getApiMajorList, getRestfulMallIndustries } from "@/assets/api";

    const props = defineProps({
        modelValue: {
            type: Boolean,
            default: false,
        },
        title: {
            type: String,
            default: '选择店铺',
        },
        placeholder: {
            type: String,
            default: '店铺名称搜索',
        },
        params: {
            type: Object,
            default: () => {
                return {}
            },
        },
        keyName: {
            type: String,
            default: '',
        },
        ids: {
            type: Array,
            default: () => {
                return []
            },
        },
        hideIds: {
            type: Array,
            default: () => {
                return []
            },
        },
        concatData: {
            type: Array,
            default: () => {
                return []
            },
        },
        max: {
            type: Number,
            default: 0
        },
    })

    // 是否设置最大可选数量
    const isMax = computed(() => {
        return props.max > 0;
    })
    // 选中数量
    const doneNumber = computed(() => {
        return checkListData.value.length;
    })
    const maxTitle = computed(() => {
        const text: string = `已选${doneNumber.value}`;
        return `${isMax.value ? `(${text}/${props.max})` : `(${text})`}`
    })

    const emit = defineEmits(['update:modelValue', 'change']);
    let dialogVisible = ref<boolean>(false);// 显示弹窗
    // 关闭弹窗
    const cancelDialog = () => {
        dialogVisible.value = false;
    }
    // 关闭弹窗
    const closeDialog = () => {
        cancelDialog();
        emit('update:modelValue', dialogVisible.value)
    }

    const params = ref<ObjValueAny>({});// 列表筛选参数
    let emptyText = ref<string>('');// 接口请求加载中
    let listData: ObjValueAny[] = [];// 列表所有数据
    let searchListData = ref<ObjValueAny[]>([]);// 列表显示数据
    let checkListData = ref<ObjValueAny[]>([]);// 已选择数据
    let disLoading = ref<boolean>(false);// 按钮禁用
    let tableLoading = ref<boolean>(false);// 列表loading
    let firstIndustry = ref<ObjValueAny[]>([]);// 一级行业列表
    let secondIndustry = ref<ObjValueAny[]>([]);// 二级行业列表
    let industryId: number = 0;// 筛选行业id

    const mdSearch = async () => {
        searchListData.value = await getDataList();
        getCheckAll();
        getEmptyText();
    }

    const getRowKeys = (row: ObjValueAny) => {
        return row.id;
    }

    const handleSelectionChange = (val: ObjValueAny[]) => {
        if (val.length > props.max && isMax.value) {
            ElMessage.closeAll();
            ElMessage.warning(`最多可选 ${props.max} 个`);
            let delRow = val.pop();
            multipleTableRef.value!.toggleRowSelection(delRow, false);
        } else {
            checkListData.value = val;
        }
        getCheckAll();
    }

    // 全选
    const multipleTableRef = ref<InstanceType<typeof ElTable>>();
    const handleCheckAll = (bool: boolean) => {
        if (bool) {
            multipleTableRef.value!.toggleAllSelection();
        } else {
            for (let delRow of searchListData.value) {
                multipleTableRef.value!.toggleRowSelection(delRow, false);
            }
        }
    }
    const checkAll = ref<boolean>(false);// 是否全选
    const indeterminate = ref<boolean>(false);// 有选中 未全选

    const getCheckAll = () => {
        const checkIds = getSearchCheckListData();
        checkAll.value = !!(searchListData.value?.length && searchListData.value?.length === checkIds?.length);
        indeterminate.value = !!(searchListData.value?.length && checkIds?.length && searchListData.value?.length !== checkIds?.length)
    }
    // 搜索后显示列表的选中项 非全部选中项
    const getSearchCheckListData = () => {
        const listDict: ObjValueAny = {};
        for (let row of searchListData.value) {
            listDict[row.id] = true;
        }
        const checkIds = [];
        for (let row of checkListData.value) {
            if (listDict[row.id]) checkIds.push(row.id);
        }
        return checkIds;
    }

    const getDataList = (): Promise<ObjValueAny[]> => {
        return new Promise(resolve => {
            tableLoading.value = true;
            getApiMajorList({
                page_size: 3000,
                MINA: 1,
                ...params.value
            }, { noReport: 1 }).then((resp: ObjValueAny) => {
                tableLoading.value = false;
                if (resp.code !== 200) {
                    ElMessage.error(resp.msg);
                    resolve([]);
                }
                const _data: ObjValueAny[] = [];
                for (let row of resp.data) {
                    if (!props.hideIds.includes(row.id)) {
                        _data.push(row);
                    }
                }
                resolve(_data);
            })
        })
    }
    const getIndustry = () => {
        return new Promise(resolve => {
            getRestfulMallIndustries({
                page: 1,
                per_page: 10000,
                filter_shop: 1,
                parent_id: industryId,
            }).then((resp: ObjValueAny) => {
                if (resp.code !== 200) {
                    ElMessage.error(resp.msg);
                    resolve([]);
                }
                resolve(resp?.data || []);
            })
        })
    }

    const initFirstIndustry = () => {
        firstIndustry.value = [{ id: 0, name: '全部一级行业' }]
    }
    const initSecondIndustry = () => {
        secondIndustry.value = [{ id: 0, name: '全部二级行业' }]
    }

    const changeFirstIndustry = (id: number) => {
        industryId = id || 0;
        initSecondIndustry();
        nextTick(() => {
            params.value.first_industry = industryId;
            params.value.second_industry = 0;
            mdSearch();
            if (id > 0) {
                getRestfulMallIndustries().then((resp: ObjValueAny) => {
                    secondIndustry.value = secondIndustry.value.concat(resp.data);
                });
            }
        })
    }
    const changeSecondIndustry = (id: number) => {
        industryId = id || 0;
        nextTick(() => {
            params.value.second_industry = industryId;
            mdSearch();
        })
    }

    const initParams = () => {
        industryId = 0;
        params.value.keyword = '';
        params.value.first_industry = 0;
        params.value.second_industry = 0;
    }

    const getEmptyText = () => {
        emptyText.value = searchListData.value.length ? '' : '暂无数据';
    }
    watch(() => props.modelValue, (newVal: boolean) => {
        dialogVisible.value = newVal;
        if (newVal) {
            emptyText.value = '加载中...';
            disLoading.value = true;
            initParams();
            initFirstIndustry();
            initSecondIndustry();
            Promise.all([getIndustry(), getDataList()]).then((resp: ObjValueAny) => {
                firstIndustry.value = firstIndustry.value.concat(resp[0]);
                listData = resp[1];
                searchListData.value = listData;
                for (let i = 0; i < listData.length; i++) {
                    const row: ObjValueAny = listData[i];
                    if (props.ids.includes(row.id)) {
                        checkListData.value.push(row);
                        multipleTableRef.value!.toggleRowSelection(row, undefined)
                    }
                }
                disLoading.value = false;
                getCheckAll();
                getEmptyText();
            })
        } else {
            listData = [];
            searchListData.value = [];
            checkListData.value = [];
            multipleTableRef.value!.clearSelection();
        }
    })

    // 确认选择
    const onDialog = () => {
        onChange(checkListData.value);
    }
    // emit 事件
    const onChange = (list: ObjValueAny[] = [], key: string = props.keyName) => {
        const ids: number[] = list.map((row: ObjValueAny) => {
            return row.id
        });
        const text: string = list.length ? (`${list[0].name} ${list.length > 1 ? `等${list.length}家` : ''}`) : '';
        emit('change', ids, text, list, key);
        cancelDialog();
    }

    const getStoreDataList = async () => {
        initParams();
        return await getDataList();
    }
    const refGetModelValue = (data: ObjValueAny[] = [], ids: number[] = [], key?: string) => {
        const _storeData: ObjValueAny[] = [];
        for (let i = 0; i < data.length; i++) {
            const row: ObjValueAny = data[i];
            if (ids.includes(row.id)) {
                _storeData.push(row);
            }
        }
        onChange(_storeData, key);
    }
    defineExpose({
        getStoreDataList,
        refGetModelValue,
    })
</script>